home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / GLE / MARTINI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.5 KB  |  251 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1997.  */
  3.  
  4. /* This program is freely distributable without licensing fees  and is
  5.    provided without guarantee or warrantee expressed or  implied. This
  6.    program is -not- in the public domain. */
  7.  
  8. /* compile: cc -o martini martini.c trackball.c -lgle -lglut -lGLU -lGL -lXmu -lXext -lX11 -lm */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <math.h>       /* for cos(), sin(), and sqrt() */
  14. #include <GL/glut.h>
  15. #include <GL/tube.h>
  16. #include "trackball.h"
  17.  
  18. int spinning = 0, moving = 0;
  19. int beginx, beginy;
  20. int W = 300, H = 300;
  21. float curquat[4];
  22. float lastquat[4];
  23. int newModel = 1;
  24. /* *INDENT-OFF* */
  25. GLfloat lightZeroPosition[] = {10.0, 4.0, 10.0, 1.0};
  26. GLfloat lightZeroColor[] = {0.8, 1.0, 0.8, 1.0}; /* green-tinted */
  27. GLfloat lightOnePosition[] = {-1.0, -2.0, 1.0, 0.0};
  28. GLfloat lightOneColor[] = {0.6, 0.3, 0.2, 1.0}; /* red-tinted */
  29. /* *INDENT-ON* */
  30.  
  31. void
  32. recalcModelView(void)
  33. {
  34.   GLfloat m[4][4];
  35.  
  36.   glPopMatrix();
  37.   glPushMatrix();
  38.   build_rotmatrix(m, curquat);
  39.   glMultMatrixf(&m[0][0]);
  40.   newModel = 0;
  41. }
  42.  
  43. /* the arrays in which we will store out polyline */
  44. #define NPTS 25
  45. double points[NPTS][3];
  46. double radii[NPTS];
  47. int idx = 0;
  48.  
  49. #define REV(r, y) { \
  50.   points[idx][0] = 0.0; \
  51.   points[idx][1] = y - 3.0; \
  52.   points[idx][2] = 0.0; \
  53.   radii[idx] = r; \
  54.   idx ++; \
  55. }
  56.  
  57. void 
  58. InitStuff(void)
  59. {
  60.   /* Initialize the join style here, no capping. */
  61.   gleSetJoinStyle(TUBE_NORM_EDGE | TUBE_JN_ANGLE);
  62.   gleSetNumSlices(30);
  63.   REV(0.0, 5.0);
  64.   REV(0.0, 4.0);
  65.   REV(2.5, 6.1);
  66.   REV(2.75, 6.0);
  67.   REV(2.75, 5.75);
  68.   REV(0.25, 3.75);
  69.   REV(0.25, 2.66);
  70.   REV(0.4, 2.5);
  71.   REV(0.3, 2.2);
  72.   REV(0.4, 1.9);
  73.   REV(0.25, 1.7);
  74.   REV(0.25, 0.6);
  75.   REV(0.25, 0.101);
  76.   REV(2.0, 0.1);
  77.   REV(2.0, 0.0);
  78.   REV(0.0, 0.05);
  79.   REV(0.0, -1.0);
  80.  
  81.   /* Capture rendering of martini glass in a display list. */
  82.   glNewList(1, GL_COMPILE);
  83.   glFrontFace(GL_CW);
  84.   glePolyCone(4, points, NULL, radii);
  85.   glFrontFace(GL_CCW);
  86.   glePolyCone(15, &points[1], NULL, &radii[1]);
  87.   glFrontFace(GL_CW);
  88.   glePolyCone(4, &points[13], NULL, &radii[13]);
  89.   glEndList();
  90. }
  91.  
  92. void
  93. redraw(void)
  94. {
  95.   if (newModel)
  96.     recalcModelView();
  97.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  98.   /* Draw the martini glass. */
  99.   glCallList(1);
  100.   glutSwapBuffers();
  101. }
  102.  
  103. void
  104. myReshape(int w, int h)
  105. {
  106.   glViewport(0, 0, w, h);
  107.   W = w;
  108.   H = h;
  109. }
  110.  
  111. void
  112. mouse(int button, int state, int x, int y)
  113. {
  114.   if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  115.     spinning = 0;
  116.     glutIdleFunc(NULL);
  117.     moving = 1;
  118.     beginx = x;
  119.     beginy = y;
  120.   }
  121.   if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  122.     moving = 0;
  123.   }
  124. }
  125.  
  126. void
  127. animate(void)
  128. {
  129.   add_quats(lastquat, curquat, curquat);
  130.   newModel = 1;
  131.   glutPostRedisplay();
  132. }
  133.  
  134. void
  135. motion(int x, int y)
  136. {
  137.   if (moving) {
  138.     trackball(lastquat,
  139.       (2.0 * beginx - W) / W,
  140.       (H - 2.0 * beginy) / H,
  141.       (2.0 * x - W) / W,
  142.       (H - 2.0 * y) / H
  143.       );
  144.     beginx = x;
  145.     beginy = y;
  146.     spinning = 1;
  147.     glutIdleFunc(animate);
  148.   }
  149. }
  150.  
  151. GLboolean lightZeroSwitch = GL_TRUE, lightOneSwitch = GL_TRUE;
  152.  
  153. void
  154. controlLights(int value)
  155. {
  156.   switch (value) {
  157.   case 1:
  158.     lightZeroSwitch = !lightZeroSwitch;
  159.     if (lightZeroSwitch) {
  160.       glEnable(GL_LIGHT0);
  161.     } else {
  162.       glDisable(GL_LIGHT0);
  163.     }
  164.     break;
  165.   case 2:
  166.     lightOneSwitch = !lightOneSwitch;
  167.     if (lightOneSwitch) {
  168.       glEnable(GL_LIGHT1);
  169.     } else {
  170.       glDisable(GL_LIGHT1);
  171.     }
  172.     break;
  173. #ifdef GL_MULTISAMPLE_SGIS
  174.   case 3:
  175.     if (glIsEnabled(GL_MULTISAMPLE_SGIS)) {
  176.       glDisable(GL_MULTISAMPLE_SGIS);
  177.     } else {
  178.       glEnable(GL_MULTISAMPLE_SGIS);
  179.     }
  180.     break;
  181. #endif
  182.   case 4:
  183.     glutFullScreen();
  184.     break;
  185.   case 5:
  186.     exit(0);
  187.     break;
  188.   }
  189.   glutPostRedisplay();
  190. }
  191.  
  192. void
  193. vis(int visible)
  194. {
  195.   if (visible == GLUT_VISIBLE) {
  196.     if (spinning)
  197.       glutIdleFunc(animate);
  198.   } else {
  199.     if (spinning)
  200.       glutIdleFunc(NULL);
  201.   }
  202. }
  203.  
  204. int
  205. main(int argc, char **argv)
  206. {
  207.   glutInit(&argc, argv);
  208.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  209.   trackball(curquat, 0.0, 0.0, 0.0, 0.0);
  210.   glutCreateWindow("martini");
  211.   glutDisplayFunc(redraw);
  212.   glutReshapeFunc(myReshape);
  213.   glutVisibilityFunc(vis);
  214.   glutMouseFunc(mouse);
  215.   glutMotionFunc(motion);
  216.   glutCreateMenu(controlLights);
  217.   glutAddMenuEntry("Toggle right light", 1);
  218.   glutAddMenuEntry("Toggle left light", 2);
  219.   if (glutGet(GLUT_WINDOW_NUM_SAMPLES) > 0) {
  220.     glutAddMenuEntry("Toggle multisampling", 3);
  221.     glutSetWindowTitle("martini (multisample capable)");
  222.   }
  223.   glutAddMenuEntry("Full screen", 4);
  224.   glutAddMenuEntry("Quit", 5);
  225.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  226.   glEnable(GL_CULL_FACE);
  227.   glEnable(GL_DEPTH_TEST);
  228.   glEnable(GL_LIGHTING);
  229.   glMatrixMode(GL_PROJECTION);
  230.   gluPerspective( /* field of view in degree */ 40.0,
  231.   /* aspect ratio */ 1.0,
  232.     /* Z near */ 1.0, /* Z far */ 40.0);
  233.   glMatrixMode(GL_MODELVIEW);
  234.   gluLookAt(0.0, 0.0, 15.0,  /* eye is at (0,0,15) */
  235.     0.0, 0.0, 0.0,      /* center is at (0,0,0) */
  236.     0.0, 1.0, 0.);      /* up is in positive Y direction */
  237.   glPushMatrix();       /* dummy push so we can pop on model recalc */
  238.   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  239.   glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
  240.   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
  241.   glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
  242.   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
  243.   glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
  244.   glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
  245.   glEnable(GL_LIGHT0);
  246.   glEnable(GL_LIGHT1);
  247.   InitStuff();
  248.   glutMainLoop();
  249.   return 0;             /* ANSI C requires main to return int. */
  250. }
  251.